package com.sdstc.modules.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.ruoyi.common.enums.MechanismType;
import com.ruoyi.common.enums.OrganType;
import com.ruoyi.common.enums.PersonStatus;
import com.ruoyi.common.enums.PlanStatus;
import com.sdstc.modules.dao.OrgDao;
import com.sdstc.modules.dao.PersonDao;
import com.sdstc.modules.dao.PlanDao;
import com.sdstc.modules.eneity.OrgEntity;
import com.sdstc.modules.eneity.PersonEntity;
import com.sdstc.modules.eneity.PlanEntity;
import com.sdstc.modules.service.OrgService;
import com.sdstc.modules.service.ScreenService;
import com.sdstc.modules.uitl.TreeUtils;
import com.sdstc.modules.vo.EchartsDataVo;
import com.sdstc.modules.vo.OrgTreeVo;
import com.sdstc.modules.vo.ScreenVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author ：wk
 * @date ：Created in 2022/11/25 11:03
 */
@Service
@Slf4j
public class ScreenServiceImpl implements ScreenService {

    @Autowired
    private OrgDao orgDao;

    @Autowired
    private OrgService orgService;

    @Autowired
    private PersonDao personDao;

    @Autowired
    private PlanDao planDao;

    public ScreenVo getScreen(){
        ScreenVo screenVo = new ScreenVo();
        // 机构
        ScreenVo.OrgScreen orgScreen = new ScreenVo.OrgScreen();
        // 济南市公安局id
        String orgId = orgService.getJNOrg().get("orgId");
        List<OrgEntity> allOrg = orgDao.selectList(new QueryWrapper<>());
        // 获取改机构下面的所有的机构
        List<OrgTreeVo> orgList = TreeUtils.getAllOrgScreen(orgId, allOrg);
        // 所有的机构
        Map<String, OrgEntity> allOrg2Map = allOrg.stream().collect(Collectors.toMap(OrgEntity::getId, Function.identity()));
        OrgEntity jnOrg = allOrg2Map.get(orgId);

        orgScreen.getOrgScreenName().add(MechanismType.INTERNAL.getInfo());
        orgScreen.getOrgScreenName().add(MechanismType.UNDER.getInfo());
        orgScreen.getOrgScreenName().add(MechanismType.DISPATCH.getInfo());
        orgScreen.getOrgScreenName().add(MechanismType.CAUSE.getInfo());
        orgScreen.getOrgScreenValue().add((int) orgList.stream().filter(o -> Objects.equals(o.getOrgType(), MechanismType.INTERNAL.getCode())).count());
        orgScreen.getOrgScreenValue().add((int) orgList.stream().filter(o -> Objects.equals(o.getOrgType(), MechanismType.UNDER.getCode())).count());
        orgScreen.getOrgScreenValue().add((int) orgList.stream().filter(o -> Objects.equals(o.getOrgType(), MechanismType.DISPATCH.getCode())).count());
        orgScreen.getOrgScreenValue().add((int) orgList.stream().filter(o -> Objects.equals(o.getOrgType(), MechanismType.CAUSE.getCode())).count());

        String specialOrg = "部门领导，分局领导";
        orgScreen.setOrgScreenTotal((int) orgList.stream().filter(o -> !specialOrg.contains(o.getOrgName())).count());

        // 编制
        ScreenVo.OrganScreen organScreen = new ScreenVo.OrganScreen();

        Integer organizationAdmin = Objects.nonNull(jnOrg.getOrganizationAdmin()) ? jnOrg.getOrganizationAdmin() : 0;
        Integer organizationSingle = Objects.nonNull(jnOrg.getOrganizationSingle()) ? jnOrg.getOrganizationSingle() : 0;
        Integer organizationWork = Objects.nonNull(jnOrg.getOrganizationWork()) ? jnOrg.getOrganizationWork() : 0;
        Integer organizationCause = Objects.nonNull(jnOrg.getOrganizationCause()) ? jnOrg.getOrganizationCause() : 0;

        EchartsDataVo admin = new EchartsDataVo();
        admin.setName(OrganType.ADMIN.getInfo());
        admin.setValue(organizationAdmin);
        organScreen.getOrganScreenList().add(admin);
        EchartsDataVo single = new EchartsDataVo();
        single.setName(OrganType.SINGLE.getInfo());
        single.setValue(organizationSingle);
        organScreen.getOrganScreenList().add(single);
        EchartsDataVo work = new EchartsDataVo();
        work.setName(OrganType.WORK.getInfo());
        work.setValue(organizationWork);
        organScreen.getOrganScreenList().add(work);
        EchartsDataVo cause = new EchartsDataVo();
        cause.setName(OrganType.CAUSE.getInfo());
        cause.setValue(organizationCause);
        organScreen.getOrganScreenList().add(cause);
        organScreen.setOrganScreenTotal(organizationAdmin + organizationSingle + organizationWork + organizationCause);

        List<String> orgIdList = orgList.stream().map(OrgTreeVo::getId).collect(Collectors.toList());

        // 人员
        ScreenVo.PersonScreen personScreen = new ScreenVo.PersonScreen();
        List<PersonEntity> personList = personDao.selectList(new QueryWrapper<PersonEntity>().in("status", Arrays.asList(PersonStatus.OK.getCode(),PersonStatus.HIGH.getCode())).in("org_Id", orgIdList));

        // 人员 根据orgId分组
        Map<String, List<PersonEntity>> orgId2Map = personList.stream().filter(o -> Objects.nonNull(o.getOrgId())).collect(Collectors.groupingBy(PersonEntity::getOrgId));

        // 人员去重
        Map<Object, Boolean> map = new HashMap<>();
        personList = personList.stream().filter(p -> map.putIfAbsent(p.getPoliceNo() + p.getIdentityNo(), Boolean.TRUE) == null).collect(Collectors.toList());

        Integer personAdmin = (int) personList.stream().filter(p -> Objects.equals(p.getPostBigCateCode(), OrganType.ADMIN.getCode())).count();
        Integer personSingle = (int) personList.stream().filter(p -> Objects.equals(p.getPostBigCateCode(), OrganType.SINGLE.getCode())).count();
        Integer personWork = (int) personList.stream().filter(p -> Objects.equals(p.getPostBigCateCode(), OrganType.WORK.getCode())).count();
        Integer personCause = (int) personList.stream().filter(p -> Objects.equals(p.getPostBigCateCode(), OrganType.CAUSE.getCode())).count();

        EchartsDataVo pAdmin = new EchartsDataVo();
        pAdmin.setName(OrganType.ADMIN.getInfo());
        pAdmin.setValue(personAdmin);
        personScreen.getPersonScreenList().add(pAdmin);
        EchartsDataVo pSingle = new EchartsDataVo();
        pSingle.setName(OrganType.SINGLE.getInfo());
        pSingle.setValue(personSingle);
        personScreen.getPersonScreenList().add(pSingle);
        EchartsDataVo pWork = new EchartsDataVo();
        pWork.setName(OrganType.WORK.getInfo());
        pWork.setValue(personWork);
        personScreen.getPersonScreenList().add(pWork);
        EchartsDataVo pCause = new EchartsDataVo();
        pCause.setName(OrganType.CAUSE.getInfo());
        pCause.setValue(personCause);
        personScreen.getPersonScreenList().add(pCause);
        personScreen.setPersonScreenTotal(personAdmin+personSingle+personWork+personCause);
        // 超编
        ScreenVo.OverEmptyScreen overEmptyScreen = screenVo.buildOverEmptyScreen(organScreen,personScreen);

        // 轮播详情，xx分局详情
        // 济南市公安局
        List<ScreenVo.OrgDetail> orgDetailList = new ArrayList<>();

        // 获取父机构为济南市公安局的 不包括部门领导、分局领导
        List<OrgEntity> thirdOrg = allOrg.stream().filter(o -> Objects.equals(o.getPid(), orgId) && !specialOrg.contains(o.getOrgName())).collect(Collectors.toList());

        for (OrgEntity orgEntity : thirdOrg) {
            ScreenVo.OrgDetail orgDetail = new ScreenVo.OrgDetail();

            orgDetail.setOrgName(orgEntity.getOrgName());

            List<ScreenVo.OrganDetail> organDetailList = new ArrayList<>();

            ScreenVo.OrganDetail adminDetail = new ScreenVo.OrganDetail();
            adminDetail.setOrganType(OrganType.ADMIN.getInfo());
            adminDetail.setPresets(orgEntity.getOrganizationAdmin());
            adminDetail.setReal(buildReal(allOrg,orgEntity.getId(),OrganType.ADMIN.getCode(),allOrg2Map,orgId2Map));

            ScreenVo.OrganDetail singleDetail = new ScreenVo.OrganDetail();
            singleDetail.setOrganType(OrganType.SINGLE.getInfo());
            singleDetail.setPresets(orgEntity.getOrganizationSingle());
            singleDetail.setReal(buildReal(allOrg,orgEntity.getId(),OrganType.SINGLE.getCode(),allOrg2Map,orgId2Map));

            ScreenVo.OrganDetail workDetail = new ScreenVo.OrganDetail();
            workDetail.setOrganType(OrganType.WORK.getInfo());
            workDetail.setPresets(orgEntity.getOrganizationWork());
            workDetail.setReal(buildReal(allOrg,orgEntity.getId(),OrganType.WORK.getCode(),allOrg2Map,orgId2Map));


            ScreenVo.OrganDetail causeDetail = new ScreenVo.OrganDetail();
            causeDetail.setOrganType(OrganType.CAUSE.getInfo());
            causeDetail.setPresets(orgEntity.getOrganizationSingle());
            causeDetail.setReal(buildReal(allOrg,orgEntity.getId(),OrganType.CAUSE.getCode(),allOrg2Map,orgId2Map));

            organDetailList.add(adminDetail);
            organDetailList.add(singleDetail);
            organDetailList.add(workDetail);
            organDetailList.add(causeDetail);

            orgDetail.setOrganDetailList(organDetailList);
            orgDetailList.add(orgDetail);
        }

        // 近期拟调整方案
        List<PlanEntity> planEntities = planDao.selectList(new QueryWrapper<PlanEntity>().eq("status", PlanStatus.Effective.getCode())
                .orderByDesc("effect_time")
                .last("limit 5"));


        screenVo.setOrgScreen(orgScreen);
        screenVo.setOrganScreen(organScreen);
        screenVo.setPersonScreen(personScreen);
        screenVo.setOverEmptyScreen(overEmptyScreen);
        screenVo.setPlanList(planEntities);
        screenVo.setOrgDetailList(orgDetailList);
        return screenVo;
    }

    public int buildReal(List<OrgEntity> allOrg, String orgId,String organType,Map<String, OrgEntity> allOrg2Map,Map<String, List<PersonEntity>> orgId2Map) {

        // 该机构
        OrgEntity orgEntityItself = allOrg2Map.get(orgId);

        List<OrgTreeVo> orgTreeItselfList;

        List<OrgTreeVo> orgTreeVos = TreeUtils.getOrgId2ListOrgTreeVo().get(orgId);

        if (CollectionUtils.isNotEmpty(orgTreeVos)){
            orgTreeItselfList = orgTreeVos;
        }else {
            orgTreeItselfList = TreeUtils.getAllOrg(orgId, allOrg);
        }

        orgTreeItselfList.add(OrgTreeVo.getInstance(orgEntityItself));

        //获取该机构下面以及该机构的所有人员
        List<String> orgItselfIds =
                orgTreeItselfList.stream().map(OrgTreeVo::getId).distinct().collect(Collectors.toList());
        List<PersonEntity> personItSelfEntities = new ArrayList<>();

        for (String orgItselfId : orgItselfIds) {
            if (CollectionUtils.isNotEmpty(orgId2Map.get(orgItselfId))){
                personItSelfEntities.addAll(orgId2Map.get(orgItselfId));
            }
        }

        return (int) personItSelfEntities.stream().filter(p -> Objects.equals(organType, p.getPostBigCateCode())).count();

    }

}
